﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MapLibrary.Players.Skills;
using Microsoft.Xna.Framework.Graphics;
using GUILibrary;
using MapLibrary.GUI;

namespace MapLibrary.Players
{
    public abstract class Skill : IActivatable, ITrackable
    {
        protected int level;
        protected int[] proteinLevels;

        /// <summary>
        /// This is the amount of protein needed to level.
        /// Set these values in the constructor for the specific Skills.
        /// </summary>
        protected int[] proteinToLevel;

        public int Level
        {
            get { return level; }
            set { level = value; }
        }

        public int[] ProteinLevels
        {
            get { return proteinLevels; }
        }

        public int[] ProteinToLevel
        {
            get { return proteinToLevel; }
        }

        public Skill()
        {
            level = 1;
            proteinLevels = new int[] { 0, 0, 0 };
            proteinToLevel = new int[] { 100, 100, 100 };
        }

        public void LoadFromData(SkillData data)
        {
            for (int i = 0; i < 3; i++)
            {
                proteinLevels[i] = data.ProteinAmounts[i].Value;
                proteinToLevel[i] = data.ProteinToLevel[i].Value;
            }

            level = data.CurrentLevel.Value;
        }

        public SkillData GetData()
        {
            SkillData d = new SkillData();
            d.ProteinAmounts = new List<IntWrapper>();

            for (int i = 0; i < 3; i++)
            {
                d.ProteinAmounts.Add(new IntWrapper(proteinLevels[i]));
                d.ProteinToLevel.Add(new IntWrapper(proteinToLevel[i]));
            }

            d.CurrentLevel = new IntWrapper(Level);

            return d;
        }

        public abstract void Update();

        public abstract void Activate(Player p);

        public abstract bool ActivateConditionsSatisfied(Player p);

        public abstract void DrawAtPlayer(SpriteBatch batch, WorldViewport viewport, Player p);

        public abstract int GetAmount(string trackerName);

        public abstract int GetMax(string trackerName);

        public virtual int GetSink(string trackerName)
        {
            return 0;
        }

        public virtual void DecrimentSink(string trackerName)
        {
            return;
        }

        public virtual void IncrimentValue(string trackerName)
        {
            return;
        }

        /// <summary>
        /// Returns true on level up, false otherwise
        /// </summary>
        /// <returns></returns>
        public virtual bool CheckAndExecuteLevelUp()
        {
            bool hasLevelUp = true;

            for (int i = 0; i < 3; i++)
            {
                if (proteinLevels[i] != proteinToLevel[i])
                    hasLevelUp = false;
            }

            if (hasLevelUp)
            {
                level += 1;

                for (int i = 0; i < 3; i++)
                {
                    proteinLevels[i] = 0;
                }
            }

            return hasLevelUp;
        }
    }
}
